<template>
	<div class="cart">
		<h4>全部商品</h4>
		<div class="cart-main">
			<div class="cart-th">
				<div class="cart-th1">全部</div>
				<div class="cart-th2">商品</div>
				<div class="cart-th3">单价（元）</div>
				<div class="cart-th4">数量</div>
				<div class="cart-th5">小计（元）</div>
				<div class="cart-th6">操作</div>
			</div>
			<div class="cart-body">
				<ul
					class="cart-list"
					v-for="cartInfo in cartInfoList"
					:key="cartInfo.id"
				>
					<li class="cart-list-con1">
						<input
							type="checkbox"
							name="chk_list"
							:checked="cartInfo.isChecked === 1 ? true : false"
							@input="
								changeSingleChecked(
									cartInfo.skuId,
									cartInfo.isChecked === 1 ? 0 : 1
								)
							"
						/>
					</li>
					<li class="cart-list-con2">
						<img :src="cartInfo.imgUrl" />
						<div class="item-msg">
							{{ cartInfo.skuName }}
						</div>
					</li>
					<li class="cart-list-con3">
						<div class="item-txt">语音升级款</div>
					</li>
					<li class="cart-list-con4">
						<span class="price">{{ cartInfo.skuPrice }}</span>
					</li>
					<li class="cart-list-con5">
						<a
							href="javascript:void(0)"
							class="mins"
							@click="updateSkuNum(cartInfo, -1)"
							>-</a
						>
						<input
							autocomplete="off"
							type="text"
							:value="cartInfo.skuNum"
							@change="changeSkuNum($event, cartInfo)"
							@focus="changeOldNum(cartInfo.skuNum)"
							minnum="1"
							class="itxt"
						/>
						<a
							href="javascript:void(0)"
							class="plus"
							@click="updateSkuNum(cartInfo, 1)"
							>+</a
						>
					</li>
					<li class="cart-list-con6">
						<span class="sum">{{ cartInfo.skuPrice * cartInfo.skuNum }}</span>
					</li>
					<li class="cart-list-con7">
						<a
							href="javascript:;"
							class="sindelet"
							@click="deleteSingle(cartInfo.skuId)"
							>删除</a
						>
						<br />
						<a href="#none">移到收藏</a>
					</li>
				</ul>
			</div>
		</div>
		<div class="cart-tool">
			<div class="select-all">
				<input class="chooseAll" type="checkbox" v-model="allChecked" />
				<span>全选</span>
			</div>
			<div class="option">
				<a href="javascript:;" @click="deleteAll">删除选中的商品</a>
				<a href="#none">移到我的关注</a>
				<a href="#none">清除下柜商品</a>
			</div>
			<div class="money-box">
				<div class="chosed">
					已选择 <span>{{ allNum }}</span
					>件商品
				</div>
				<div class="sumprice">
					<em>总价（不含运费） ：</em>
					<i class="summoney">{{ allPrice }}</i>
				</div>
				<div class="sumbtn">
					<router-link class="sum-btn" to="/trade">结算</router-link>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
import {
	reqShopCartList,
	reqCheckCart,
	reqDeleteCart,
	reqAllChecked,
	addOrupdateShopCart,
	reqDeleteAll,
} from "@/api";
export default {
	name: "ShopCart",
	data() {
		return {
			cartInfoList: [],
			oldNum: 1, //保存数量的旧值
		};
	},
	mounted() {
		//初始化请求购物车数据
		this.getShopCartList();
	},
	methods: {
		//1.初始化请求购物车数据
		async getShopCartList() {
			try {
				const result = await reqShopCartList();
				// console.log(result);
				//三元表达式写法:如果得到的result的索引为0有响应内容,则返回索引为0内的cartInfoList对象数据,索引0不存在(返回undefined),则返回空数组
				// this.cartInfoList = result[0] ? result[0].cartInfoList : [];
				// 可选链操作符写法(适情况书写):如果索引值为0为undefined则直接返回前面不再向后读取,索引值为真也就是确实能读取到数据,才会向后读取数据内cartInfoList的属性
				// this.cartInfoList = result[0]?.cartInfoList;
				// 注意点:两种方法有共通之处,不过如果返回undefined的时候数据驱动渲染视图时可能会存在异常情况,所以最好是推荐返回一个对象较好
				//因为未来要判断每一个数据的是否在发送修改数量的是否请求状态,所以我们给每一个数据都添加一个isReq的属性
				this.cartInfoList = result[0]?.cartInfoList.map((item) => {
					item.isReq = false; //是否在请求中
					return item;
				});
			} catch (e) {
				alert(e.message);
			}
		},

		//2. 请求修改单个选中状态
		async changeSingleChecked(skuID, isChecked) {
			try {
				await reqCheckCart(skuID, isChecked);
				alert("修改成功");

				//重新发送购物车数据请求
				this.getShopCartList();
			} catch (e) {
				alert(e.message);
			}
		},

		//3. 请求删除某一个购物车数据
		async deleteSingle(skuId) {
			try {
				await reqDeleteCart(skuId);
				//重新发送购物车数据请求
				this.getShopCartList();
			} catch (e) {
				alert(e);
			}
		},

		//4. 点击按钮数量的改动
		async updateSkuNum(cartInfo, skuNum) {
			//1.先判断当前被修改的数据是否在请求状态????(如果正在请求则直接返回)
			if (cartInfo.isReq) return;

			//2. 如果放行了,则立即把isReq设置为true(直到请求完成才能设置为false)
			cartInfo.isReq = true;

			try {
				//判断计算后商品的数量小于等于0,则直接不再操作
				//5. 在这个位置停止请求操作,我们也要把isReq设置为false
				if (cartInfo.skuNum + skuNum <= 0) return (cartInfo.isReq = false);

				await addOrupdateShopCart(cartInfo.skuId, skuNum);
				// alert("修改数量成功");
				//重新发送购物车数据请求
				//6.我们也到await等待重新的请求完成才可以下一步的执行
				await this.getShopCartList();

				//3. 一旦请求成功,则直接把isReq设置为false
				cartInfo.isReq = false;
			} catch (e) {
				//4. 一旦请求失败,则直接把isReq设置为false
				alert(e.message);
			}
		},

		//5.批量删除
		async deleteAll() {
			//首先过滤出被选中的值,然后收集被选中的值的id
			const skuIdList = this.cartInfoList.reduce((p, c) => {
				if (c.isChecked === 1) {
					p.push(c.skuId);
				}
				return p;
			}, []);

			try {
				await reqDeleteAll(skuIdList);
				alert("批量删除成功");
			} catch (e) {
				alert(e.message);
			}
		},

		//6.直接修改数量的input值
		async changeSkuNum(e, cartInfo) {
			//校验正则
			const reg = /^[0-9]+$/g;
			//修改后并失去焦点的值
			const value = e.target.value;
			//判断这个值是否符合条件
			if (!reg.test(value) || value <= 0) {
				//如果不符合条件 则直接使用保存好的旧值覆盖当前输入的值
				e.target.value = this.oldNum;
				return;
			}

			//如果输入的符合条件,则要发送请求
			//首先计算出来改变的差值是多少?
			const centerNum = e.target.value - cartInfo.skuNum;
			try {
				await addOrupdateShopCart(cartInfo.skuId, centerNum);
				await this.getShopCartList();
				alert("修改成功");
			} catch (e) {
				alert(e.message);
			}
		},

		//7.数量获取焦点事件
		changeOldNum(skuNum) {
			//只要获取焦点 就把当前表单的值设置给oldNum
			this.oldNum = skuNum;
		},
	},

	computed: {
		//全选的控制数据
		allChecked: {
			get() {
				return this.cartInfoList?.every((item) => {
					return item.isChecked === 1;
				});
			},
			async set(newVal) {
				try {
					//首先得到skuIdList(所有的商品id组成的数组)
					const skuIdList = this.cartInfoList.map((item) => {
						return item.skuId;
					});

					await reqAllChecked(newVal ? 1 : 0, skuIdList);
					alert("修改所有商品状态成功");

					//重新发送购物车数据请求
					this.getShopCartList();
				} catch (e) {
					alert(e.message);
				}
			},
		},

		//总商品数量
		allNum() {
			//计算所有商品的总数量
			// this.cartInfoList.reduce((p, c) => p + c.skuNum, 0);
			return this.cartInfoList.reduce((p, c) => {
				if (c.isChecked === 1) {
					p += c.skuNum;
				}
				return p;
			}, 0);
		},

		//总商品价格
		allPrice() {
			//计算所有商品的总价格
			// this.cartInfoList.reduce((p, c) => p + c.skuNum * c.skuPrice, 0);
			return this.cartInfoList.reduce((p, c) => {
				if (c.isChecked === 1) {
					p += c.skuNum * c.skuPrice;
				}
				return p;
			}, 0);
		},
	},
};
</script>

<style lang="less" scoped>
.cart {
	width: 1200px;
	margin: 0 auto;

	h4 {
		margin: 9px 0;
		font-size: 14px;
		line-height: 21px;
	}

	.cart-main {
		.cart-th {
			background: #f5f5f5;
			border: 1px solid #ddd;
			padding: 10px;
			overflow: hidden;

			& > div {
				float: left;
			}

			.cart-th1 {
				width: 25%;

				input {
					vertical-align: middle;
				}

				span {
					vertical-align: middle;
				}
			}

			.cart-th2 {
				width: 25%;
			}

			.cart-th3,
			.cart-th4,
			.cart-th5,
			.cart-th6 {
				width: 12.5%;
			}
		}

		.cart-body {
			margin: 15px 0;
			border: 1px solid #ddd;

			.cart-list {
				padding: 10px;
				border-bottom: 1px solid #ddd;
				overflow: hidden;

				& > li {
					float: left;
				}

				.cart-list-con1 {
					width: 4.1667%;
				}

				.cart-list-con2 {
					width: 25%;

					img {
						width: 82px;
						height: 82px;
						float: left;
					}

					.item-msg {
						float: left;
						width: 150px;
						margin: 0 10px;
						line-height: 18px;
					}
				}

				.cart-list-con3 {
					width: 20.8333%;

					.item-txt {
						text-align: center;
					}
				}

				.cart-list-con4 {
					width: 12.5%;
				}

				.cart-list-con5 {
					width: 12.5%;

					.mins {
						border: 1px solid #ddd;
						border-right: 0;
						float: left;
						color: #666;
						width: 6px;
						text-align: center;
						padding: 8px;
					}

					input {
						border: 1px solid #ddd;
						width: 40px;
						height: 33px;
						float: left;
						text-align: center;
						font-size: 14px;
					}

					.plus {
						border: 1px solid #ddd;
						border-left: 0;
						float: left;
						color: #666;
						width: 6px;
						text-align: center;
						padding: 8px;
					}
				}

				.cart-list-con6 {
					width: 12.5%;

					.sum {
						font-size: 16px;
					}
				}

				.cart-list-con7 {
					width: 12.5%;

					a {
						color: #666;
					}
				}
			}
		}
	}

	.cart-tool {
		overflow: hidden;
		border: 1px solid #ddd;

		.select-all {
			padding: 10px;
			overflow: hidden;
			float: left;

			span {
				vertical-align: middle;
			}

			input {
				vertical-align: middle;
			}
		}

		.option {
			padding: 10px;
			overflow: hidden;
			float: left;

			a {
				float: left;
				padding: 0 10px;
				color: #666;
			}
		}

		.money-box {
			float: right;

			.chosed {
				line-height: 26px;
				float: left;
				padding: 0 10px;
			}

			.sumprice {
				width: 200px;
				line-height: 22px;
				float: left;
				padding: 0 10px;

				.summoney {
					color: #c81623;
					font-size: 16px;
				}
			}

			.sumbtn {
				float: right;

				a {
					display: block;
					position: relative;
					width: 96px;
					height: 52px;
					line-height: 52px;
					color: #fff;
					text-align: center;
					font-size: 18px;
					font-family: "Microsoft YaHei";
					background: #e1251b;
					overflow: hidden;
				}
			}
		}
	}
}
</style>
